파이썬 (0406) 5주차

numpy
Author

김보람

Published

April 6, 2022

import

!pip install numpy 
Collecting numpy
  Downloading numpy-1.24.1-cp39-cp39-win_amd64.whl (14.9 MB)
     --------------------------------------- 14.9/14.9 MB 10.7 MB/s eta 0:00:00
Installing collected packages: numpy
Successfully installed numpy-1.24.1
import numpy as np

넘파이 공부 1단계

선언

list([1,2,3])
[1, 2, 3]
[1,2,3]
[1, 2, 3]
a=np.array([1,2,3])  # list만들고 ndarray화 시킴
l=[1,2,3]

기본연산 브로드캐스팅

a
array([1, 2, 3])
l
[1, 2, 3]
a+1 ## [1,2,3] + 1 = [2,3,4]
array([2, 3, 4])
l+1
TypeError: can only concatenate list (not "int") to list
a+np.array([-1,-2,-3])
array([0, 0, 0])
a-a
array([0, 0, 0])
l-l  # 리스트는 안됨
TypeError: unsupported operand type(s) for -: 'list' and 'list'
a*2
array([2, 4, 6])
l*2
[1, 2, 3, 1, 2, 3]
a/2
array([0.5, 1. , 1.5])
l/2
TypeError: unsupported operand type(s) for /: 'list' and 'int'
a**2
array([1, 4, 9])
l**2
TypeError: unsupported operand type(s) for ** or pow(): 'list' and 'int'
a%2   # %2 = 2로 나눈 나머지 리턴
array([1, 0, 1], dtype=int32)
l%2
TypeError: unsupported operand type(s) for %: 'list' and 'int'

기타 수학연산 지원

np.sqrt(2)
1.4142135623730951
np.sqrt(a), np.sqrt(l)
(array([1.        , 1.41421356, 1.73205081]),
 array([1.        , 1.41421356, 1.73205081]))
np.log(a), np.log(l)
(array([0.        , 0.69314718, 1.09861229]),
 array([0.        , 0.69314718, 1.09861229]))
np.exp(a), np.exp(l)
(array([ 2.71828183,  7.3890561 , 20.08553692]),
 array([ 2.71828183,  7.3890561 , 20.08553692]))
np.sin(a), np.sin(l)
(array([0.84147098, 0.90929743, 0.14112001]),
 array([0.84147098, 0.90929743, 0.14112001]))

넘파이 공부 2단계

인덱싱 1차원

- 선언

l=[11,22,33,44,55,66]
a=np.array(l)

- 인덱스로 접근

l[0], l[1], l[2], l[3], l[4], l[5]
(11, 22, 33, 44, 55, 66)
a[0], a[1], a[2], a[3], a[4], a[5]
(11, 22, 33, 44, 55, 66)

- : 이용 (슬라이싱)

l[2:4] # index 2에서 시작, index 4는 포함하지 않음
[33, 44]
a[2:4]
array([33, 44])

- 점수배열에 의한 익덱싱

a
array([11, 22, 33, 44, 55, 66])
  a[[0,2,4]]  # index=0, index=2, index=4 에 해당하는 원소를 뽑고 싶다 -> 가능
array([11, 33, 55])
 l[[0,2,4]]    # 리스트는 불가능
TypeError: list indices must be integers or slices, not list

- 부울값에 의한 인덱싱

a
array([11, 22, 33, 44, 55, 66])
a[[True, True, False, True, False, False]]
array([11, 22, 44])

응용하면?

a<33
array([ True,  True, False, False, False, False])
a[[ True,  True, False, False, False, False]]
array([11, 22])
a[a<33]
array([11, 22])

리스트는 불가능

l<33
TypeError: '<' not supported between instances of 'list' and 'int'
l[[True, True, False, True, False, False]]
TypeError: list indices must be integers or slices, not list

인덱싱 2차원

- 중첩리스트와 2차원 np.array 선언

A = [[1,2,3,4],[-1,-2,-3,-4],[5,6,7,8],[-5,-6,-7,-8]]
A2 = np.array(A)
A2
array([[ 1,  2,  3,  4],
       [-1, -2, -3, -4],
       [ 5,  6,  7,  8],
       [-5, -6, -7, -8]])
A
[[1, 2, 3, 4], [-1, -2, -3, -4], [5, 6, 7, 8], [-5, -6, -7, -8]]

- A의 원소 인덱싱

A[0][0] # A의 (1,1)의 원소
1
A[1][2] # A의 (2,3)의 원소
-3
A[-1][0] # A의 (4,1)의 원소
-5

- A2의 원소 인덱싱

A2[0][0]
1
A2[1][2] # A2의 (2,3)의 원소
-3
A2[-1][0] # A2의 (4,1)의 원소
-5

- A2에서만 되는 기술 (넘파이에서 제시하는 신기술, R에서는 기본적으로 쓰던것, 이중list는 불가능)

A2[0,0]
1
A2[1,2] # A2의 (2,3)의 원소
-3
A2[-1,0] # A2의 (4,1)의 원소
-5

- 정수배열에 의한 인덱싱 & 슬라이싱!

A2
array([[ 1,  2,  3,  4],
       [-1, -2, -3, -4],
       [ 5,  6,  7,  8],
       [-5, -6, -7, -8]])
A2[0,0:2]   # 1행 1열, 1행 2열
array([1, 2])
A2[0,:]  # 1행
array([1, 2, 3, 4])
A2[0]  # 1행
array([1, 2, 3, 4])
A2[[0,2],:]   # 1행, 3행
array([[1, 2, 3, 4],
       [5, 6, 7, 8]])
A2[[0,2]]   # 1행, 3행
array([[1, 2, 3, 4],
       [5, 6, 7, 8]])
A2[:,0] # 1열
array([ 1, -1,  5, -5])
A2[:,[0]] # 1열
array([[ 1],
       [-1],
       [ 5],
       [-5]])
A2[:,[0,2]] # 1열, 3열
array([[ 1,  3],
       [-1, -3],
       [ 5,  7],
       [-5, -7]])
A2[0:2,[0,2]]  # 1행-2행 / 1열-3열
array([[ 1,  3],
       [-1, -3]])

1차원 배열의 선언

- 리스트나 튜플을 선언하고 형변환

np.array((1,2,3)) # 튜플->넘파이어레이
array([1, 2, 3])
np.array([1,2,3]) # 리스트->넘파이어레이
array([1, 2, 3])

- range()를 이용해서 선언하고 형변환

np.array(range(10))  # range(10)->넘파이어레이
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

- np.zeros, np.ones

np.zeros(3)
array([0., 0., 0.])
np.ones(4)
array([1., 1., 1., 1.])

- np.linspace

np.linspace(0,1,12)   # 0부터 1까지 12개로 쪼개기   (양끝점 모두 포함)
array([0.        , 0.09090909, 0.18181818, 0.27272727, 0.36363636,
       0.45454545, 0.54545455, 0.63636364, 0.72727273, 0.81818182,
       0.90909091, 1.        ])
len(np.linspace(0,1,12))
12

- np.arange

np.arange(5)  #np.array(range(5))
array([0, 1, 2, 3, 4])
np.arange(1,6)   #np.array(range(1,6))
array([1, 2, 3, 4, 5])

reshape

- reshape: ndarray의 특수한 기능

a=np.array([11,22,33,44,55,66])
a  #길이가 6인 벡터
array([11, 22, 33, 44, 55, 66])
type(a)
numpy.ndarray
a.reshape
<function ndarray.reshape>
a.reshape(2,3)  # (2,3) matrix라고 생각해도 무방
array([[11, 22, 33],
       [44, 55, 66]])
a.reshape(5,2)
ValueError: cannot reshape array of size 6 into shape (5,2)

note: reshape은 a자체를 변홧키는 것은 아님

a  # reshape은 a자체는 변화하지 않음
array([11, 22, 33, 44, 55, 66])
b=a.reshape(2,3)  # a를 reshape한 결과를 b에 저장
b
array([[11, 22, 33],
       [44, 55, 66]])
 a  # a는 여전히 그대로 있음
array([11, 22, 33, 44, 55, 66])

- 다시 b를 a처럼 바꾸고 싶다.

b
array([[11, 22, 33],
       [44, 55, 66]])
b.reshape(6) # b는 (2,3) matrix, 그런데 이것을 길이가 6인 벡터로 만들고 싶다.
array([11, 22, 33, 44, 55, 66])
a.shape   # 길이가 1인 튜플
(6,)
b.shape   # 길이가 2인 튜플이니까 2차원 
(2, 3)

- reshape with -1

a=np.arange(24)  #np.array(range(24))
a
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23])
a.reshape(2,?) # 에러..
SyntaxError: invalid syntax (2529973538.py, line 1)
a.reshape(2,-1)
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11],
       [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]])
a.reshape(3,-1)
array([[ 0,  1,  2,  3,  4,  5,  6,  7],
       [ 8,  9, 10, 11, 12, 13, 14, 15],
       [16, 17, 18, 19, 20, 21, 22, 23]])
a.reshape(4,-1)
array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11],
       [12, 13, 14, 15, 16, 17],
       [18, 19, 20, 21, 22, 23]])
a.reshape(7,-1)  # 나눠떨어지지 않으니까.. 
ValueError: cannot reshape array of size 24 into shape (7,newaxis)
b=a.reshape(12,-1)
b
array([[ 0,  1],
       [ 2,  3],
       [ 4,  5],
       [ 6,  7],
       [ 8,  9],
       [10, 11],
       [12, 13],
       [14, 15],
       [16, 17],
       [18, 19],
       [20, 21],
       [22, 23]])
b.reshape(24) # b를 다시 길이가 24인 벡터로 만들고 싶다.
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23])
b.reshape(-1) # b를 다시 길이가 24인 벡터로 만들고 싶다.
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23])

2차원 배열의 선언


np.zeros((3,3))
array([[0., 0., 0.],
       [0., 0., 0.],
       [0., 0., 0.]])
np.ones((3,3))
array([[1., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.]])
np.eye(3) 
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])
np.diag([1,2,3,-1])
array([[ 1,  0,  0,  0],
       [ 0,  2,  0,  0],
       [ 0,  0,  3,  0],
       [ 0,  0,  0, -1]])

랜덤으로 생성

np.random.randn(10)  # 표준정규분포에서 10개를 뽑음
array([-1.62694735, -0.46057632,  0.9092888 , -0.52150285, -0.0409467 ,
        0.98561001,  1.87613924, -2.08870029,  0.28577046, -0.15794105])
np.random.rand(10)  # 0~1 사이에서 10개를 뽑음
array([0.7377278 , 0.61091057, 0.17571601, 0.29298532, 0.90149596,
       0.84002052, 0.50700681, 0.40217981, 0.30557984, 0.34392417])
np.random.randn(4).reshape(2,2)  # 표준정규분포에서 4개를 뽑고 (2,2) nparray로 형태변환
array([[0.50093512, 0.74336071],
       [0.91296027, 0.04033486]])
np.random.rand(4).reshape(2,2)  # 0~1에서 4개를 뽑고 (2,2) nparray로 형태변환
array([[0.30484011, 0.57731961],
       [0.30645542, 0.2189475 ]])

행렬

A=np.array(range(4)).reshape(2,2)
A
array([[0, 1],
       [2, 3]])
A.T #전치행렬
array([[0, 2],
       [1, 3]])
np.linalg.inv(A)   # 역행렬
array([[-1.5,  0.5],
       [ 1. ,  0. ]])
A @ np.linalg.inv(A)  # 단위행렬   # @는 행렬곱을 수행
array([[1., 0.],
       [0., 1.]])

숙제

A=np.array(range(6))
A # 길이가 6인 벡터
array([0, 1, 2, 3, 4, 5])

위와 같이 길이가 6인 벡터 A를 (2,3) ndarray로 변경

A.reshape(2,3)
array([[0, 1, 2],
       [3, 4, 5]])
len(A.reshape(2,3))
2